package com.github.bryx.workflow.config;

import com.github.bryx.workflow.exception.WorkflowRuntimeException;
import com.github.bryx.workflow.handler.Aware;
import com.github.bryx.workflow.handler.WorkflowInstanceAware;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @Author jameswu
 * @Date 2021/6/11
 **/
@Component
@Slf4j
public class WorkflowInstanceAwareRegistry implements InitializingBean {

    @Autowired
    ApplicationContext applicationContext;

    Map<String, WorkflowInstanceAware> workflowInstanceAwares = Maps.newHashMap();

    public void register(String processDefKey, WorkflowInstanceAware workflowInstanceAware){
        workflowInstanceAwares.put(processDefKey, workflowInstanceAware);
    }

    public WorkflowInstanceAware getWorkflowInstanceAware(String processDefKey){
        return workflowInstanceAwares.get(processDefKey);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        String[] beanNamesForAnnotation = applicationContext.getBeanNamesForAnnotation(Aware.class);
        for (String beanName : beanNamesForAnnotation){
            Object bean = applicationContext.getBean(beanName);
            if (!(bean instanceof WorkflowInstanceAware)){
                throw new WorkflowRuntimeException(String.format("%s must implement interface $s",bean.getClass(), WorkflowInstanceAware.class));
            }
            Aware annotation = AnnotationUtils.findAnnotation(bean.getClass(), Aware.class);
            String[] processKeys = annotation.processKey();
            for(String processKey : processKeys){
                this.register(processKey, (WorkflowInstanceAware)bean);
                log.debug("register workflow aware 【{}】 on process【{}】", bean.getClass(), processKey);
            }
        }
    }


}
